# coding=utf-8
import os
import sys
import time
import re
import logging
import base64

# Create your views here.
from django.db.models import Case, When, IntegerField

from bid.ai_generate.get_team import get_team
from bid.generate.tools.dawate import main_stream
from bid.generate.models import ExBid, ExBidTeam, ExTeam, ExFile

t = time.time()
import requests
import json
import logging
from datetime import datetime
from zentao.settings import PYMYSQL_CONF, DIFY_URL, ROOT_FOLDER
# DIFY_URL = 'http://127.0.0.1:8083'
# PYMYSQL_CONF = {
#     'host': '127.0.0.1',
#     # 'host': '172.16.159.132',
#     'password': '123456',
#     # 'password': 'Sqdmm123#',
#     'port': 3306,  # MySQL服务端口
#     'user': 'root',
#     'database': 'zentao',
#     'charset': 'utf8mb4'
# }

current_time = datetime.now()

import os

# 设置日志
# ptah = "./out_log/"
# if not os.path.exists(ptah):
#     os.mkdir(ptah)
#
# logging.basicConfig(level=logging.DEBUG,
#                     format='%(asctime)s - %(levelname)s - %(message)s',
#                     filename='./out_log/' + current_time.strftime("%Y-%m-%d_%H-%M-%S") + 'dawate_log.txt',
#                     filemode='a')  # 追加模式

#大瓦特回复
def dawate_streaming(content, config_params):

    # config_params = {
    #     'relAppId': '17987690',
    #     'appId': '17987868',
    #     'appSecret': '5570ea83260dbcad482a7c9175411d5e',
    #     # 'messages': [{"role": "user", "content": ''.join(["你是谁"]*5000)}]
    #     'messages': [{"role": "user", "content": content}]
    #     # 'messages': ls
    # }

    config_params['messages'] = [{"role": "user", "content": content}]

    answer = ''
    response_content = main_stream(config_params)
    try:
        while True:
            a = next(response_content)
            answer += a
            print(a,end='')
    except StopIteration:
            pass

    #回答去除think部分
    answer = answer.split('</think>')[-1]

        # global_thread['其他'].append([extra['1'],answer])

    return answer


import pymysql


def db_connet():
    # conn = pymysql.connect(
    #     host='127.0.0.1',  # 连接名称，默认127.0.0.1
    #     user='root',  # 用户名
    #     passwd='123456',  # 密码
    #     port=3306,  # 端口，默认为3306
    #     db='zentao',  # 数据库名称
    #     charset='utf8',  # 字符编码
    # )
    conn = pymysql.connect(**PYMYSQL_CONF)
    print("----数据库连接成功------", conn)
    logging.info("----数据库连接成功------ %s", conn)
    return conn


def data_base_connet(sql_statement):
    # 获取游标
    conn = db_connet()
    cursor = conn.cursor()
    print(cursor)

    # 执行sql语句execute和executemany
    # 定义要执行的SQL语句列表
    try:
        cursor.execute(sql_statement)
        hearders = [description[0] for description in cursor.description]
        results = cursor.fetchall()

        # print(results)

        cursor.close()  # 关闭查询游标
        conn.commit()  # 事务的提交
        conn.close()  # 查询完毕，需要关闭连接，释放计算机资源
        # print('sql执行成功')

        return hearders, results
    except pymysql.MySQLError as e:
        print(f"An error occurred: {e}")
        cursor.close()  # 关闭查询游标
        conn.commit()  # 事务的提交
        conn.close()  # 查询完毕，需要关闭连接，释放计算机资源
        # print('sql执行成功')
        return e, None

def slice_text(text, slice_length):
    slices = []
    slices_new = []
    current_slice = ""
    current_length = 0
    title = ''
    if ':' in text:
        title = text.split('：')[0]
    for char in text:
        current_slice += char
        current_length += 1

        # 当当前切片长度接近1000时，开始寻找分割点
        if current_length >= slice_length:
            # 查找最近的）》号或上一个标点符号
            split_point = re.search(r'》|[^，。！？；：]', current_slice[::-1])
            if split_point:
                # 获取分割点的真实位置
                split_index = len(current_slice) - split_point.start()
                # 添加切片到列表
                slices.append(current_slice[:split_index])
                # 重置当前切片和长度计数器
                current_slice = current_slice[split_index:]
                current_length = len(current_slice)

    # 添加最后一个切片
    if current_slice:
        slices.append(current_slice)
    for i, slice in enumerate(slices):
        if i == 0:
            print(f"切片{i + 1}：长度为：{len(slice)}{slice}\n")
            slices_new.append(slice)
        else:
            print(f"切片{i + 1}：长度为：{len(slice)}{title + slice}\n")
            slices_new.append(title + slice)
    return slices_new


def split_list_into_chunks(lst, chunk_size=5000):
    """
    Splits a list of strings into chunks of a specified size, ensuring that individual strings are not split.

    :param lst: List of strings to be split.
    :param chunk_size: Maximum size of each chunk.
    :return: List of chunks.
    """
    chunks = []
    current_chunk = []

    for item in lst:
        # If adding this item to the current chunk exceeds the chunk size, start a new chunk
        if len(item) > chunk_size:
            print('长度超长了：', len(item))
            slices = slice_text(item, chunk_size)
            for s_i in slices:
                current_chunk.append(s_i)
        if sum(len(x) for x in current_chunk) + len(item) > chunk_size:
            chunks.append(''.join(current_chunk))
            current_chunk = [item]
        else:
            current_chunk.append(item)

    # Add the last chunk if it's not empty
    if current_chunk:
        chunks.append(''.join(current_chunk))

    return chunks

#对剩余团队成员按照工作年限和证书数量排序，优先工作年限
def sorted_rule(item):
    work_years = int(item['工作年限'])
    cert_num = len([i for i in item['证书'] if i != ''])

    return (work_years, cert_num)

#文本基于url的base64编码(+替换成-，/替换成_，=替换成.)
def url_bs64_encode(string):
    bs64_str = str(base64.b64encode(string.encode("utf-8")), "utf-8")
    return  bs64_str.replace('+','-').replace('/','_').replace('=','.')

def team_filter(user_input, bid_id, company, dept, config_params):
    '''

    团队内容生成测试：

    :return:
    '''
    sql_statement = f'''
            SELECT
        t1.id AS 用户id,
        t1.name AS 姓名,
        t1.workYears AS 工作年限,
        t2.name AS 证书名称,
        t2.type AS 证书类型,
        t2.level AS 证书级别,
        d.name AS 部门,
        t1.degree AS 学位
    FROM
        ex_team t1
    LEFT JOIN
        ex_teamQualification t2
    ON
        t1.account = t2.account
    LEFT JOIN
        ex_dept d
    ON 
        t1.dept = d.id
    WHERE (t2.expirationDate is null or t2.expirationDate>now())
        AND t1.company={company}

            '''
    headers, results = data_base_connet(sql_statement)
    if results is not None:
        #对数据做一下处理，将多个证书归纳到一起
        res = {}
        for i in results:
            if i[0] not in res.keys():
                #可能不存在工作年限
                if i[2]:
                    work_years = i[2]
                else:
                    work_years = '0'
                res[i[0]] = {'用户id':i[0],'部门':i[-2],'学位':i[-1],'姓名':i[1],'工作年限':work_years,'证书':[]}
            if i[4]:
                cert_type = i[4]
            else:
                cert_type = '无类别'
            if i[5]:
                cert_level = i[5]
            else:
                cert_level = '无级别'
            if i[3]:
                cert = i[3]
            else:
                cert = ''

            if cert != '':
                res[i[0]]['证书'].append(f"{cert}({cert_type}-{cert_level})")

        #整理成列表
        headers = ['用户id','部门','学位','姓名','工作年限','证书']
        results = []
        for value in res.values():
            results.append([value['用户id'],value['部门'],value['学位'],value['姓名'],value['工作年限'],'、'.join(value['证书'])])

        results_new = [str(i) for i in results]
        split_segments_tem = split_list_into_chunks(results_new, chunk_size=5000)
        split_segments = [str(headers) + str(i) for i in split_segments_tem]
        # query = input('请输入你的问题:')
        # query='找出中级以上的用户有哪些'
        local_conversation_id = ''
        # while True:
        # user_input = input('用户输入要求：')
        # user_input='''
        # 要求：1、项目固定服务技术团队3人（含）以上，团队少于3人的得0分，3人以上得2分；2、项目经理具备CISP证书或信息系统项目集成工程师，均不具备的得0分，具备其中1证的得3分，都具备的得5分；3、服务工程师均具备CCNP或HCNP或H3CNE证书，有1人不具备的得0分，均具备1-2证的得3分，均具备2证以上的得5分；4、项目经理具有3年以上信息安全工作经验，服务工程师均具有1年以上的信息安全项目运维实施工作经验，不满足条件的得0分，满足1项条件的得2分，均满足条件的得3分。
        #
        # '''
        # if '再见' in user_input:
        #     data_answ, conversation_id = dify_chat2('要求：' + str((user_input)), conversation_id=conversation_id)
        #     print('再见：', data_answ)
        # else:
        answer_merge = []
        # prompt_1 = '''
        # 提示词：帮我进行项目经理以及团队成员推荐，只需一个项目经理，团队成员推荐中不需要包含项目经理，如果没有团队人数要求为0即可，并对团队进行评分，并且根据证书级别对用户进行归类。
        # 并以json格式输出：{"推荐项目经理为": {"用户id","xxx","姓名"："xxx"}，
        #                 "推荐团队成员为": [{"用户id"："xxx"，"姓名"："xxx","拥有证书"："xxx"},
        #                                 {"用户id"："xxx"，"姓名"："xxx","拥有证书"："xxx"}],
        #                 "团队人数": n,
        #                 "团队评分为": "xxx分",
        #                 "中级证书成员有": [{"用户id"："xxx"，"姓名"："xxx","拥有证书"："xxx"},
        #                                 {"用户id"："xxx"，"姓名"："xxx","拥有证书"："xxx"}],
        #                 "高级证书成员有": [{"用户id"："xxx"，"姓名"："xxx","拥有证书"："xxx"},
        #                                 {"用户id"："xxx"，"姓名"："xxx","拥有证书"："xxx"}]
        #                                 }
        # '''
        prompt_1 = f'''
                        帮我进行项目经理以及团队成员推荐，项目团队中不包含项目经理
                        
                        ###项目经理要求###
                        只需一个项目经理，并且项目经理必须从部门为{dept}的人中选择，其中只有明确为职称的证书才属于职称，其余均不为职称
                        
                        ###团队成员要求###
                        团队成员中优先放入符合条件的人员，当所有符合条件的人员不满足总人数要求时，再追加不符合条件的人员
                        
                        ###团队成员职务（两个要求选符合的那一个要求）###
                        1、团队成员还需要推荐职务，如果要求中指定了职务，则使用要求中的职务并且需要符合职务要求（不符合的成员职务为空即可）
                        2、如果要求中没有指定职务，则使用如下职务并且每个职务至少有一个：技术负责人、系统分析师、开发工程师、测试工程师、实施工程师、质量管控工程师、技术支持工程师
                        
                        ###团队人数强调###
                        团队总人数一定要满足最高要求
                        
                        以下为示例：
                        ###输入###
                        团队专业技术人员不少于50人，同时包含至少5 位持有软件类中级及以上证书人员或具备同类项目 业绩（提供参与业绩相关证明，如合同人员、验收 证书项目成员等），具有完善合理的团队稳定的保障 措施，得15分；
                        ###输出###
                        并以json格式输出：```json
                                        {{"推荐项目经理": {{"用户id":"xxx","姓名":"xxx","职务":"项目负责人"}}，
                                        "推荐团队成员": [{{"用户id":"xxx"，"姓名":"xxx","职务":"xxx"}},
                                                        {{"用户id":"xxx"，"姓名":"xxx","职务":"xxx"}}],
                                        "团队要求": "软件类中级及以上证书人员或具备同类项目业绩"}}
                                        ```
                        ###输入###
                        1）拟委派的项目经理具有 CISP证书的加2分，具有 CISSP加3分，可以累加； 2）拟委派的项目团队成员具 有1个及以上软件设计师， 得3分；每多1个软件设计 师加1分，最多加2分。 3）拟委派的项目团队成员具 有1个及以上CISP，得3分； 每多1个CISP加1分，最多 加2分。 
                        ###输出###
                        并以json格式输出：
                                        ```json
                                        {{"推荐项目经理": {{"用户id":"xxx","姓名":"xxx","职务":"项目负责人"}}，
                                        "推荐团队成员": [{{"用户id":"xxx"，"姓名":"xxx","职务":"xxx"}},
                                                        {{"用户id":"xxx"，"姓名":"xxx","职务":"xxx"}}],
                                        "团队要求": "软件设计师、CISP"}}
                                        ```
                        思考过程精简一些，json中的键必须为"用户id"、"姓名"和"职务"
                        '''
        # for index, cont_i in enumerate(split_segments):
        # print('表格切分后的内容：', len(str(cont_i)), cont_i)

        # print('========================================')
        # print(results[0],'\n',user_input,'\n',pm_std)
        # print('========================================')

        # query = f'数据为：{[headers]+results}\n团队成员要求：{user_input}\n项目经理要求：{pm_std}' + str(prompt_1)
        query = f'###提示词###\n{prompt_1}###人员数据###\n{[headers]+results}\n###团队要求###{user_input}'

        with open('ceshi.txt', 'w') as f:
            f.writelines(query)

        data_answ = dawate_streaming(query,config_params)

        # data_answ, conversation_id = dify_chat2('数据为：' + str(cont_i) + str((user_input)) + str(prompt_1),
        #                                         conversation_id=conversation_id)
        # file_.writelines(data_answ + '\n')
        # print(f'\n------结果{index}：--------\n', data_answ)
        # data_answ = data_answ.split('</think>')[-1]
        answer_merge.append(data_answ)

        print('-------模型输出结果：-------', answer_merge)
        # if len(split_segments) > 1:
        #     # data_answ, conversation_id = dify_chat2('将结果进行合并,并以json格式输出,原始的json格式不要变。' + str(answer_merge),
        #     #                                     conversation_id=conversation_id)
        #     data_answ = dawate_streaming('将结果进行合并,并以json格式输出,原始的json格式不要变。' + str(answer_merge))
        #     data_answ = ''
        #     try:
        #         while True:
        #             gen_text = next(stream_content)
        #             gen_text_split = gen_text.split('\t')
        #             local_conversation_id = gen_text_split[0]
        #             data_answ += '\t'.join(gen_text_split[1:])
        #             # sys.stdout.write(f"\r {[data_answ]}")
        #             # sys.stdout.flush()
        #
        #     except StopIteration as e:
        #         # conversation_id = e.value
        #         pass
        #     print('-----结果合并后的结果------', data_answ)

        # 获取返回的json
        pattern = r"```json(.*?)```"
        matches = re.findall(pattern, data_answ, re.DOTALL)
        if len(matches) != 0:
            llm_data = json.loads(matches[-1])
            # print('\n')

            id2position = {}
            #整理id
            header_id = llm_data['推荐项目经理']['用户id']
            id2position[header_id] = llm_data['推荐项目经理']['职务']
            team_ids = []


            for i in llm_data['推荐团队成员']:
                team_ids.append(i['用户id'])
                id2position[i['用户id']] = i['职务']
                print('推荐用户：',[i])
            # team_ids = [i['用户id'] for i in llm_data['推荐团队成员']]
            if header_id not in team_ids:
                team_ids = [header_id] + team_ids
            #

            # for i in team_ids:
            #     print(res[i])
            print('================================')

            # #筛选剩余人员，并按照工作年限和证书数量排序
            # other_person = []
            # for _id in set(res.keys())-set(team_ids):
            #     other_person.append(res[_id])
            #
            # # 根据相似度排序
            # other_person = sorted(other_person, key=lambda x: sorted_rule(x), reverse=True)
            #
            # print(len(team_ids))
            #
            # if llm_data['要求的团队人数'].isdigit():
            #     chazhi = int(llm_data['要求的团队人数']) - len(team_ids)
            # else:
            #     chazhi = 0
            #
            # if chazhi > 0:
            #     for i in other_person[:chazhi]:
            #         team_ids.append(i['用户id'])
            #         print(res[i['用户id']])
            #         # extra_person += f"{i['姓名']}(工作年限：{i['工作年限']})；"

            print(len(team_ids))
            if len(team_ids) != 0:

                #更新数据库-投标任务关联的团队表
                # 创建一个Case表达式用于排序
                preserved_order = Case(
                    *[When(id=id, then=pos) for pos, id in enumerate(team_ids)],
                    output_field=IntegerField()
                )

                #先获取团队的对象
                team = ExTeam.objects.filter(id__in=team_ids).distinct().order_by(preserved_order)
                #获取投标任务表对象
                bid = ExBid.objects.filter(id=bid_id).first()
                for account in team:
                    if str(account.id) == str(header_id):
                        position = '项目负责人'
                    else:
                        position = id2position[str(account.id)]

                    #添加到数据库
                    ExBidTeam.objects.create(
                        bid=bid,
                        account=account,
                        position=position
                    )

                #总结的话
                refer_person = [i['姓名'] for i in llm_data['推荐团队成员']]
                extra = {'cnt':len(refer_person), 'person': '、'.join(refer_person), '团队要求': llm_data['团队要求'], 'id2position':id2position}

                #生成文件
                filename, save_path = get_team('team', team_ids, bid_id, header_id,  extra)

            return header_id

if __name__ == "__main__":
    # main()

    # step1用户意图识别
    # intention_recognition()

    # step2 意图为：团队数据筛选  根据招标要求进行团队数据筛选及其团队推荐
    st = time.time()
    team_filter('1.团队专业技术人员不少于 10 人，同时包含至少 5 位持有软件类中级及以上证书人员或具备同类项目业绩（提供参与业绩相关证明，如合同人员、验收证书项目成员等），具有完善合理的团队稳定的保障措施，得 15 分；\n2.团队专业技术人员不少于 5 人，同时包含至少3 位持有软件类中级及以上证书人员或具备同类项目业绩（提供参与业绩相关证明，如合同人员、验收证书项目成员等），团队稳定的保障措施基本合理，得 10 分；\n3.团队专业技术人员不少于 3 人，同时包含至少1 位持有软件类中级及以上证书人员或具备同类项目业绩（提供参与业绩相关证明，如合同人员、验收证书项目成员等），有团队稳定的保障措施，得 5 分；\n4.其他情况或没有内容不得分。\n需提供人员证书及在职证明材料（提供在本单位投标截止日期前半年内任意连续 3 个月的社保证明或在本单位的在职劳动合同）。',3)
    # query='你是谁'
    # data_answ,conversation_id= dify_chat_streaming(str(query))
    # print(data_answ,conversation_id)